/*
 * SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

use crate::cli::ZipArgs;
use crate::error::ZipError;
use crate::utils::common::{apply_filters, copy_zip_file_to_zip, init_run_state, match_pattern};
use anyhow::Result;
use std::path::PathBuf;

pub fn execute(args: &ZipArgs) -> Result<()> {
    log::info!("Starting copy operation...");
    let mut run_state = init_run_state(args)?;

    // 匹配模式列表
    let select_files: Vec<String> = args
        .files
        .iter()
        .map(|p| p.to_string_lossy().to_string())
        .collect();

    let files_to_copy_map: std::collections::BTreeMap<String, PathBuf> = select_files
        .iter()
        .map(|p| (p.to_string(), PathBuf::new()))
        .collect();
    run_state.init_display_info(&files_to_copy_map, &args.command)?;

    let mut copy_count = 0;

    let mut writer = run_state.writer.take().expect("Writer not initialized");
    let archive = run_state.archive.take().expect("Archive not initialized");

    // 遍历原zip中的所有文件
    let mut matched_files = Vec::new();

    for i in 0..archive.len() {
        let file = archive.by_index_raw(i)?;
        let name = file.name().to_string();

        let should_copy = if select_files.is_empty() {
            true
        } else {
            select_files
                .iter()
                .any(|pattern| match_pattern(&name, pattern, args.other.no_wildcards))
        };

        if should_copy {
            // 应用复制操作的筛选逻辑
            if !apply_filters(&name, args, true) {
                log::debug!("excluding: {}", name);
                continue;
            }

            run_state.update_display_info(writer.get_current_split_index(), file.compressed_size());
            run_state.print_operation_start("copying", &name)?;
            run_state.print_operation_end_args(
                file.origin_size() as u64,
                file.compressed_size() as u64,
                file.compression_method(),
            );

            copy_count += 1;
            matched_files.push(name.clone());
            copy_zip_file_to_zip(&mut run_state, &file, &mut writer)?;
        }
    }

    // 检查是否有指定的文件未被匹配到
    if !select_files.is_empty() {
        for pattern in &select_files {
            if !matched_files
                .iter()
                .any(|name| match_pattern(name, pattern, args.other.no_wildcards))
                && !args.basic_options.quiet
            {
                println!("warning: not in archive : {}", pattern);
            }
        }
    }

    if copy_count == 0 {
        log::warn!("No files matched the specified patterns.");
        return Err(ZipError::NothingToDo(
            run_state
                .zip_file
                .clone()
                .unwrap()
                .to_string_lossy()
                .to_string(),
        )
        .into());
    }

    run_state.writer = Some(writer);
    run_state.archive = Some(archive);

    // 完成zip文件
    run_state.finish()?;

    if !args.basic_options.quiet {
        log::info!(
            "Success! Copy {} files from {}",
            copy_count,
            args.zipfile.clone().unwrap().display(),
        );
        if args.basic_options.verbose {
            run_state.print_summary_verbose();
        }
    }

    Ok(())
}
